#ifndef _MD5_H
#define _MD5_H

typedef unsigned       int uint4;
typedef unsigned short int uint2;
typedef unsigned      char uchar;


typedef struct _md5_
{
	uint4		m_State[4];
	uint4		m_Count[2];
	uchar		m_Buffer[64];
	uchar		m_Digest[16];
	uchar		m_Finalized;
} md5;


#ifdef __cplusplus
extern "C" {
#endif
	
char* PrintMD5(uchar md5Digest[16]);
char* MD5String(char* szString);
char* MD5File(const char* szFilename);


void	Init(md5 * pMd5);
void	Update(md5 *pMd5, uchar* chInput, uint4 nInputLen);
void	Finalize(md5 *pMd5);
uchar*	Digest(md5 *pMd5);
void	Transform(md5 *pMd5, uchar* block);
void	Encode(uchar* dest, uint4* src, uint4 nLength);
void	Decode(uint4* dest, uchar* src, uint4 nLength);
uint4	rotate_left(uint4 x, uint4 n);
uint4	F(uint4 x, uint4 y, uint4 z);
uint4	G(uint4 x, uint4 y, uint4 z);
uint4	H(uint4 x, uint4 y, uint4 z);
uint4	I(uint4 x, uint4 y, uint4 z);
void	FF(uint4* a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
void	GG(uint4* a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
void	HH(uint4* a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
void	II(uint4* a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);

#ifdef __cplusplus
};
#endif

#endif